import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Storage} from '@ionic/storage';
import {API} from './api'
import 'rxjs/add/operator/toPromise';
import {ToastController} from 'ionic-angular';

@Injectable()
export class HttpProvider {

  access_token: string
  refresh_token: string
  tokenType: string

  constructor(public http: HttpClient,
              public toastCtrl: ToastController,
              public storage: Storage) {

  }

  ajax(url, type = 'GET', data = {}, token = true) {
    let options = {
      url: url,
      type: type,
      params: data
    }
    if (token)
      return this.request(options)
    else {
      return this.requestWithoutToken(options)
    }
  }

  toastMsg(message: string) {
    let toast = this.toastCtrl.create({
      message: message,
      position: 'middle',
      duration: 3000
    })
    toast.present();
  }

  setTokenStorage(data) {
    return Promise.all([
      this.storage.set('access_token', data.access_token).then(d => {
        this.access_token = d
      }),
      this.storage.set('refresh_token', data.refresh_token).then(d => {
        this.refresh_token = d
      }),
      this.storage.set('tokenType', data.tokenType).then(d => {
        this.tokenType = d
      })
    ])
  }

  request(options) {
    return this.storage.get('access_token')
      .then(access_token => {
        let headers = Object.assign(options.headers ? options.headers : {}, {
          'Authorization': "bearer " + access_token
        })
        return this.http.request(options.type, options.url, {
          body: options.type == 'POST' ? options.params : {},
          params: options.type == 'GET' ? options.params : {},
          headers: headers
        })
          .toPromise()
          .then(res => {
            let code = res['errcode'] === undefined ? res['code'] : res['errcode']
            let msg = res['errmsg'] === undefined ? res['msg'] : res['errmsg']
            let data = res['data']
            if (code == '0') {
              return data
            } else {
              throw {
                code: code,
                msg: msg
              }
            }
          })
      }).catch(err => {
        let code = err.code
        if (code == '40001') {
          //40001	access_token过期，需要使用refresh_token刷新accesss_token
          return this.refreshToken().then(() => {
            this.request(options)
          }).catch(err => {
            if (err.code == '40002') {
              //40002 refresh_token过期，需要重新登录
              /*************code 添加跳转登陆界面****************/
              console.log('跳转到登陆')
            } else {
              throw err
            }
          })
        } else {
          /*************code 添加错误处理（用户可看）****************/
          throw err
        }
      })
  }

  //调用该方法需自带 catch
  refreshToken() {
    return this.storage.get('refresh_token')
      .then(refresh_token => {
        return this.http.post(API.LOGIN_REFRESH_TOKEN, {}, {
          params: {
            'refreshToken': refresh_token
          }
        })
          .toPromise()
          .then(rData => {
            let code = rData['errcode']
            let msg = rData['errmsg']
            if (code == '0') {
              return this.setTokenStorage(rData['data'])
            } else {
              throw {
                code: code,
                msg: msg
              }
            }
          })
      })
  }

  requestWithoutToken(options) {
    return this.http.request(options.type, options.url, {
      body: options.body ? options.body : {},
      params: options.params ? options.params : {},
      headers: options.headers ? options.headers : {},
    }).toPromise().then(res => {
      let code = res['errcode']
      let msg = res['errmsg']
      let data = res['data']
      if (code == '0') {
        return data
      } else {
        throw {
          code: code,
          msg: msg
        }
      }
    })
  }

  clearTokenStorage() {
    this.storage.clear().then(() => {
      console.log('删除storage')
    })
  }
}
